%scannertype LexicalParser
%scanbasetype LexicalScanner
%tokentype Token

%namespace Infinity.Parser.Lexical
%using Infinity.Parser.Syntax;

digits [0-9]+
character [a-zA-Z]+
whitespace [\r\t ]
symbol [\-\>\@\&\#\$\%\!\?\\\<\>\<\>\=\+\-\*\/\^\_]

%%

procedure				{ return (int)Token.PROCEDURE; }
function				{ return (int)Token.FUNCTION; }
operator				{ return (int)Token.OPERATOR; }

prefix  				{ return (int)Token.PREFIX; }
infix					{ return (int)Token.INFIX; }
postfix					{ return (int)Token.POSTFIX; }
iterative				{ return (int)Token.ITERATIVE; }

precedence				{ return (int)Token.PRECEDENCE; }

declare					{ return (int)Token.DECLARE; }
skip					{ return (int)Token.SKIP; }
begin					{ return (int)Token.BEGIN; }
end						{ return (int)Token.END; }
return					{ return (int)Token.RETURN; }
if						{ return (int)Token.IF; }
then					{ return (int)Token.THEN; }
else{whitespace}+if		{ return (int)Token.ELSEIF; }
else					{ return (int)Token.ELSE; }
while					{ return (int)Token.WHILE; }
loop					{ return (int)Token.LOOP; }
for						{ return (int)Token.FOR; }
foreach					{ return (int)Token.FOREACH; }
do 						{ return (int)Token.DO; }
in						{ return (int)Token.IN; }
out						{ return (int)Token.OUT; }
to						{ return (int)Token.TO; }
by						{ return (int)Token.BY; }
var						{ return (int)Token.VAR; }
const					{ return (int)Token.CONST; }
type					{ return (int)Token.TYPE; }
where					{ return (int)Token.WHERE; }


:{whitespace}*=			{ return (int)Token.ASSIGNMENT; }
; 						{ return (int)Token.END_COMMAND; }

\(						{ return (int)Token.LEFT_REGULAR_PARENTHESES; }
\)						{ return (int)Token.RIGHT_REGULAR_PARENTHESES; }
\[						{ return (int)Token.LEFT_SQUARE_PARENTHESES; }
\]						{ return (int)Token.RIGHT_SQUARE_PARENTHESES; }
\{						{ return (int)Token.LEFT_CURLY_PARENTHESES; }
\}						{ return (int)Token.RIGHT_CURLY_PARENTHESES; }

\/\/.*					;

Q{whitespace}*:			{ return (int)Token.PRECONDITION; }
R{whitespace}*:			{ return (int)Token.POSTCONDITION; }

\,						{ return (int)Token.COMMA_SEPARATOR; }
:						{ return (int)Token.COLON; }
\|						{ return (int)Token.LINEAR_COLON; }
\.\.					{ return (int)Token.DOTS; }
\.						{ return (int)Token.DOT; }


({digits}+)|({digits}+\.{digits}+)	{ return (int)Token.NUMBER; }

\"[^\"]+\"					{ return (int)Token.STRING; }

false|true				{ return (int)Token.BOOLEAN; }


({whitespace}|\n)+		;

({character})({character}|{digits})*	{ return (int)Token.IDENTIFIER; }

{symbol}+				 {	return (int)Token.SYMBOL; }


.						{
							Console.WriteLine("Unexpected character: {0}", yytext);
							return yylex();
						}
	
%%
